package com.project;

import org.apache.catalina.Context;
import org.apache.catalina.Wrapper;
import org.apache.catalina.startup.Tomcat;
import org.apache.tomcat.util.descriptor.web.FilterDef;
import org.apache.tomcat.util.descriptor.web.FilterMap;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.servlet.DispatcherServlet;

import javax.servlet.Filter;
import javax.servlet.ServletContext;

public class MainServlet {
    public MainServlet(){
        Tomcat tomcat = new Tomcat();
        tomcat.setPort(8088);
        tomcat.getConnector();
        Context context = tomcat.addContext("", null);
        this.addFilter(context, new CharacterEncodingFilter("utf-8",true), "/*");
        try {
            //注册前端控制器
            DispatcherServlet dispatcherServlet = new DispatcherServlet(this.createApplicationContext(context.getServletContext()));
            Wrapper servlet = tomcat.addServlet(context, "dispatcherServlet", dispatcherServlet);
            servlet.setLoadOnStartup(1);
            servlet.addMapping("/*");
            tomcat.start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 创建spring容器的应用上下文对象
     * @param servletContext  web容器的上下文对象
     * @return  spring容器应用上下文对象
     */
    public WebApplicationContext createApplicationContext(ServletContext servletContext) {
        AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
        ctx.register(WebApplicationConfig.class);
        ctx.setServletContext(servletContext);
        ctx.refresh();
        ctx.registerShutdownHook();
        return ctx;
    }

    public void addFilter(Context context, Filter filterObj, String...filterPaths){
        FilterDef filterDef = new FilterDef();
        filterDef.setFilter(filterObj);//设置过滤器对象
        filterDef.setFilterName(filterObj.getClass().getName());//设置过滤器名称

        FilterMap filterMap = new FilterMap();
        //设置过滤范围，可多次添加
        for(String path:filterPaths){
            filterMap.addURLPatternDecoded(path);
        }
        //该过滤范围应用的过滤器
        filterMap.setFilterName(filterObj.getClass().getName());
        //注册
        context.addFilterDef(filterDef);
        context.addFilterMap(filterMap);
    }

    public static void main(String[] args) {
        new MainServlet();
    }
}
